package com.ruoyi.car.business.service.impl;


import com.github.pagehelper.PageHelper;
import com.ruoyi.car.business.domain.BpmnInfo;
import com.ruoyi.car.business.domain.CarPackageAudit;
import com.ruoyi.car.business.domain.ServiceItem;
import com.ruoyi.car.business.mapper.CarPackageAuditMapper;
import com.ruoyi.car.business.query.CarPackageAuditQuery;
import com.ruoyi.car.business.service.IBpmnInfoService;
import com.ruoyi.car.business.service.ICarPackageAuditService;
import com.ruoyi.car.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TablePageInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.*;

@Service
@Transactional
public class CarPackageAuditServiceImpl implements ICarPackageAuditService {

    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private IBpmnInfoService bpmnInfoService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private IServiceItemService serviceItemService;

    @Autowired
    private TaskService taskService;

    @Override
    public TablePageInfo<CarPackageAudit> query(CarPackageAuditQuery qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        List<CarPackageAudit> carPackageAudits = carPackageAuditMapper.selectForList(qo);
        for (CarPackageAudit audit : carPackageAudits) {
            audit.setCreator(userService.selectUserById(Long.parseLong(audit.getCreator())).getUserName());
            if (audit.getAuditorId() != null) {
                audit.setAuditorName(userService.selectUserById(audit.getAuditorId()).getUserName());
            }
        }
        return new TablePageInfo<CarPackageAudit>(carPackageAudits);
    }


    @Override
    public void save(CarPackageAudit carPackageAudit) {

        carPackageAuditMapper.insert(carPackageAudit);
    }

    @Override
    public CarPackageAudit get(Long id) {
        return carPackageAuditMapper.selectByPrimaryKey(id);
    }


    @Override
    public void update(CarPackageAudit carPackageAudit) {
        carPackageAuditMapper.updateByPrimaryKey(carPackageAudit);
    }

    @Override
    public void deleteBatch(String ids) {
        Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : dictIds) {
            carPackageAuditMapper.deleteByPrimaryKey(dictId);
        }
    }

    @Override
    public List<CarPackageAudit> list() {
        return carPackageAuditMapper.selectAll();
    }

    @Override
    public InputStream getProcessImg(Long id) {
        InputStream inputStream = null;
        // 根据ID 查询CarPackageAudit对象
        CarPackageAudit audit = this.get(id);
        Long bpmninfoId = audit.getBpmninfoId();
        BpmnInfo bpmnInfo = bpmnInfoService.get(bpmninfoId);
        // 可以通过BpmnInfo对象获取到流程定义的ID
        BpmnModel bpmnModel = repositoryService.getBpmnModel(bpmnInfo.getActProcessId());
        List<String> highLightedActivities = null;
        // 判断是否处于正在运行的状态
        if (CarPackageAudit.STATUS_IN_ROGRESS.equals(audit.getStatus())) {
            highLightedActivities = runtimeService.getActiveActivityIds(audit.getInstanceId());
        } else {
            highLightedActivities = Collections.EMPTY_LIST;
        }
        DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
        inputStream = generator.generateDiagram(bpmnModel,
                highLightedActivities,
                Collections.EMPTY_LIST,
                "宋体",
                "宋体",
                "宋体"
        );
        return inputStream;
    }

    @Override
    public void cancelApply(Long id) {
        // 合理化校验
        CarPackageAudit audit = this.get(id);
        if (!CarPackageAudit.STATUS_IN_ROGRESS.equals(audit.getStatus())) {
            throw new GlobalException("非法操作");
        }
        carPackageAuditMapper.changeStatus(id, CarPackageAudit.STATUS_CANCEL);
        serviceItemService.changeStatus(audit.getServiceItemId(), ServiceItem.AUDITSTATUS_INIT);
        // 删除流程实例
        runtimeService.deleteProcessInstance(audit.getInstanceId(), "流程撤销");
    }

    @Override
    @Transactional
    public void audit(Long id, Integer auditStatus, String info) {
        //先判断状态
        CarPackageAudit carPackageAudit = this.get(id);
        if (carPackageAudit == null || !CarPackageAudit.STATUS_IN_ROGRESS.equals(carPackageAudit.getStatus())) {
            throw new GlobalException("只有处于审核状态的记录才能进行审核操作");
        }
        // 任务Service 根据实力流程的ID查询当前操作的所在节点 是否是当前登陆用户的待办
        Task currentTask = taskService.createTaskQuery().processInstanceId(carPackageAudit.getInstanceId()).singleResult();
        Map<String, Object> variables = new HashMap<>();
        variables.put("auditStatus", auditStatus);
        taskService.complete(currentTask.getId(), variables);
        // 判断 传入节点是否通过
        if (CarPackageAudit.STATUS_PASS.equals(auditStatus)) {
            Task nextTask = taskService.createTaskQuery().processInstanceId(carPackageAudit.getInstanceId()).singleResult();
            if (nextTask == null) {
                // 修改状态审核通过状态
                carPackageAudit.setStatus(CarPackageAudit.STATUS_PASS);
                carPackageAudit.setAuditorId(null);
                serviceItemService.changeStatus(carPackageAudit.getServiceItemId(), ServiceItem.AUDITSTATUS_APPROVED);
            } else {
                // 设置审核对象  当前审核人ID设置为下一个节点处理人
                carPackageAudit.setAuditorId(Long.parseLong(nextTask.getAssignee()));
            }
        } else {
            // 修改状态为拒绝状态
            carPackageAudit.setStatus(CarPackageAudit.STATUS_REJECT);
            carPackageAudit.setAuditorId(null);
            // 调整ServiceItem的状态
            serviceItemService.changeStatus(carPackageAudit.getServiceItemId(), ServiceItem.AUDITSTATUS_REPLY);
        }
        carPackageAudit.setAuditTime(new Date());
        SysUser user = ShiroUtils.getSysUser();
        // 设置审核人的ID集  获取之前的审核人ID 在添加本次审核人的ID
        carPackageAudit.setAuditUserIds(carPackageAudit.getAuditUserIds() + user.getUserId() + ",");
        String infoStr = CarPackageAudit.STATUS_PASS.equals(auditStatus) ? "同意" : "拒绝";
        carPackageAudit.setInfo(carPackageAudit.getInfo() + "<br>" + user.getUserName() + infoStr + ", 批注: " + info);
        this.updateFromAudit(carPackageAudit);
    }

    private void updateFromAudit(CarPackageAudit carPackageAudit) {
        carPackageAuditMapper.updateFromAudit(carPackageAudit);
    }
}
